home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume26 / pico / part01 next >
Encoding:
Text File  |  1991-12-14  |  46.5 KB  |  2,004 lines

  1. Newsgroups: comp.sources.misc
  2. From: byron@archone.tamu.edu (Byron Rakitzis)
  3. Subject:  v26i111:  pico - A picture editor for SGI, Sun, Part01/01
  4. Message-ID: <1991Dec15.021403.21349@sparky.imd.sterling.com>
  5. X-Md4-Signature: 9a12d1665543613b332f8c20c2b7cc6b
  6. Date: Sun, 15 Dec 1991 02:14:03 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: byron@archone.tamu.edu (Byron Rakitzis)
  10. Posting-number: Volume 26, Issue 111
  11. Archive-name: pico/part01
  12. Environment: SGI, Sun4, ANSI-C
  13.  
  14. I've spent some time working on a picture editor described in Gerard
  15. Holzman's book "The Digital Darkroom". I don't really have the time to
  16. take this program all the way, so I thought I'd offer to the net what
  17. results I have so far.  This program is *not* a full-blown implementation 
  18. of pico.  However, I think the code is interesting enough that someone 
  19. might be able to do something quite useful with it without too much effort.
  20.  
  21. I have a version of pico which compiles MIPS and SPARC code on the fly,
  22. and which can deal with simple C expressions which refer to bitmaps in
  23. terms of cartesian coordinates (x,y).  It supports 512x512 8-bit
  24. greyscale image files (in pgm format).
  25.  
  26. Despite its limitations, it is a fun toy to play with.  Compared to
  27. "popi", a pico interpreter posted to the net a few months back, this
  28. program has far fewer features, but also runs one or two orders of
  29. magnitude faster (I am not making this up).
  30.  
  31. Byron.
  32. ---------
  33. #! /bin/sh
  34. # This is a shell archive.  Remove anything before this line, then feed it
  35. # into a shell via "sh file" or similar.  To overwrite existing files,
  36. # type "sh file -c".
  37. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  38. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  39. # Contents:  README Makefile alloc.c dpy.c expr.y file.c gen.c main.c
  40. #   mipsgen.c mk.c nodpy.c patchlevel.h pico.h sparcgen.c
  41. # Wrapped by kent@sparky on Sat Dec 14 20:00:03 1991
  42. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  43. echo If this archive is complete, you will see the following message:
  44. echo '          "shar: End of archive 1 (of 1)."'
  45. if test -f 'README' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'README'\"
  47. else
  48.   echo shar: Extracting \"'README'\" \(5093 characters\)
  49.   sed "s/^X//" >'README' <<'END_OF_FILE'
  50. Xpico -- 1st approximation, Byron Rakitzis, 12/10/91.
  51. X
  52. XThis is a first stab at an implementation of pico, the picture editor
  53. Xfrom Bell Labs described in Gerard Holzman's book "The Digital
  54. XDarkroom".
  55. X
  56. XThis program is *not* a full-blown implementation of pico. However, I
  57. Xthink the code is interesting enough that someone might be able to do
  58. Xsomething quite useful with it without too much effort.
  59. X
  60. XHOW TO BUILD PICO:
  61. X
  62. XPico runs on SGI's and Sun-4's. Edit the Makefile to get the right 
  63. Xcompiler and LDFLAGS. On a Sun4, you will need gcc or Sun's ansi
  64. Xcc, since pico is written with prototypes and new-style definitions.
  65. X
  66. XHOW TO USE IT:
  67. X
  68. XThere are two options to pico, "-n" and "-d". "-n" suppresses the
  69. Xdisplay output, and "-d" provides an assembly dump of the generated
  70. Xcode after each expression is typed (using "dis" on the SGI and "adb"
  71. Xon the Sun).
  72. X
  73. XIf you type "pico" you are prompted with a ">". You can now try typing
  74. Xin a C expression involving x and y. The greyscale value of the point
  75. X[x,y] is determined by the value of the expression you type. e.g.,
  76. X
  77. X    > x+y
  78. X
  79. Xcreates a series of diagonal bands, since at x+y == 256 the grey
  80. Xvalue wraps from white to black. x*y is striking, as is x^y, x*x+y*y
  81. Xand many others.
  82. X
  83. XYou can refer to the current image as old[x,y], e.g.,
  84. X
  85. X    > old[y,x]
  86. X
  87. Xrotates the current image 90 degrees. The "u" command performs one
  88. Xlevel of undo, alternating between the current and previous images.
  89. X
  90. XIf you create a file that you like, you can write it out (in pgm
  91. Xformat) with the "w" command. Use double quotes to quote any special
  92. Xcharacters in the filename. i.e.,
  93. X
  94. X    > w foo
  95. Xbut
  96. X    > w "/tmp/foo"
  97. X
  98. XSimilarly, "r" can be used to read pgm files (which for now must be
  99. X512x512, 8-bit greyscale images).
  100. X
  101. XOnce you have a file, you can always refer to it by the shorthand "$n"
  102. Xwhere n is the number of the file in the order it was read/written.
  103. XType "f" to see what files you have in memory.
  104. X
  105. XFor example, to combine chris and dmr (the two sample bitmaps in the
  106. Xftp directory) so that chris fades into dmr from left to right, you can
  107. Xtry:
  108. X
  109. X    > r dmr
  110. X    > r chris
  111. X    > (x*dmr + (X-x)*chris) / (2*X)
  112. X        [this can also be entered as]
  113. X    > (x*$1 + (X-x)*$2) / (2*X)
  114. X
  115. Xto reflect dmr's face along the line y=256, do:
  116. X
  117. X    y < Y/2 ? dmr[x,Y-y] : dmr
  118. X
  119. X(X refers to the constant 512, the maximum x coordinate. The other
  120. Xbuilt in constants are Y (obvious) and Z, the maximum brightness level,
  121. X255.)
  122. X
  123. XFinally, to quit type "q" or control-D.
  124. X
  125. XHOW IT WORKS:
  126. X
  127. XThe program is made up of a parser of C expressions, a simple rd code
  128. Xgenerator for the MIPS and SPARC architectures, minimal display support
  129. Xfor the GL (Silicon Graphics) library, and file I/O in pgm format. The
  130. Ximage format is hardcoded at 512*512, 8-bit greyscale. An expression is
  131. Xcompiled straight into an array and then gets called by pico in order
  132. Xto perform the operations on the image as fast as possible. This pico
  133. Xis at least an order of magnitude faster (if not more) than the popi
  134. Xposted to the net a few months back.
  135. X
  136. XTo use this program you must be on an SGI or a Sun. The Sun version
  137. Xcurrently has no visual support, so you must explicitly write out pgm
  138. Xfiles and use "xloadimage" or some similar program to view the pico
  139. Xoutput.
  140. X
  141. XTHINGS TO DO:
  142. X
  143. XI would consider extending the program in the following ways, though I
  144. Xdon't have the time for it right now:
  145. X
  146. X1) Support different displays. Since the format of pico images is so
  147. Xsimple, 8-bit greyscale, it should be easy to pop up images on just
  148. Xabout any kind of computer with a color display. I have used pico
  149. Xcrudely under X-windows by writing a pgm file out to /tmp and then
  150. Xrunning "xloadimage /tmp/pico" in order to view the file.
  151. X
  152. X2) Extend the pico language. Right now only C expressions are
  153. Xsupported.  The only two variables recognized are x and y. This is a
  154. Xdrawback, but as I mentioned, this isn't a full-blown pico. The command
  155. Xset is limited to r, w, f, u, q. (read, write, showfiles, undo, quit)
  156. X
  157. X3) Add support for polar coordinates, transcendental functions, and so
  158. Xon. The current implementation works only with the MIPS integer unit,
  159. Xi.e., add, subtract, multiply, divide and the bit operations. The SPARC
  160. Xport is even cruder; a function call is made for every multiply, divide
  161. Xand mod operation, since there is no hardware multiply etc.  A future
  162. Xversion may address this problem by performing strength reduction on
  163. Xloops, but this is really beyond the scope of the project I started.
  164. X(However, I do perform strength reduction on power of 2 multiplies
  165. Xand divides by substituting a shift.)
  166. X
  167. X4) Support color images. A very interesting project would be to support
  168. Xarbitrary 32-bit color images, i.e., with alpha channel. This might
  169. Xactually be of use to people who need to, say, boost the alpha channel
  170. Xof a particular image file. This also entails supporting "real" image
  171. Xfile formats like rla.
  172. X
  173. X4) Support new architectures. I wrote pico on the MIPS, and spent about
  174. X2 afternoons porting it to the SPARC. Consequently, the quality of the
  175. XSPARC port is probably quite mediocre. Porting to other RISC machines,
  176. Xhowever should be equally straightforward.
  177. END_OF_FILE
  178.   if test 5093 -ne `wc -c <'README'`; then
  179.     echo shar: \"'README'\" unpacked with wrong size!
  180.   fi
  181.   # end of 'README'
  182. fi
  183. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  184.   echo shar: Will not clobber existing file \"'Makefile'\"
  185. else
  186.   echo shar: Extracting \"'Makefile'\" \(216 characters\)
  187.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  188. X# For sgi
  189. XCC=cc -prototypes -O -g 
  190. XLDFLAGS = -lgl
  191. X
  192. X# For sun4
  193. X#CC=gcc -Wall -O -g
  194. X
  195. Xobjs = y.tab.o main.o mk.o gen.o dpy.o file.o alloc.o
  196. X
  197. Xpico: $(objs)
  198. X    $(CC) -o pico $(objs) $(LDFLAGS)
  199. X
  200. Xy.tab.c: expr.y
  201. X    yacc expr.y
  202. END_OF_FILE
  203.   if test 216 -ne `wc -c <'Makefile'`; then
  204.     echo shar: \"'Makefile'\" unpacked with wrong size!
  205.   fi
  206.   # end of 'Makefile'
  207. fi
  208. if test -f 'alloc.c' -a "${1}" != "-c" ; then 
  209.   echo shar: Will not clobber existing file \"'alloc.c'\"
  210. else
  211.   echo shar: Extracting \"'alloc.c'\" \(2113 characters\)
  212.   sed "s/^X//" >'alloc.c' <<'END_OF_FILE'
  213. X/* alloc.c: a simple single-arena allocator for command-line-lifetime allocation */
  214. X
  215. X#include "pico.h"
  216. X
  217. Xtypedef struct Block Block;
  218. X
  219. Xstatic struct Block {
  220. X    size_t used, size;
  221. X    char *mem;
  222. X    Block *n;
  223. X} *fl, *ul;
  224. X
  225. X/* alignto() works only with power of 2 blocks and assumes 2's complement arithmetic */
  226. X#define alignto(m, n)   ((m + n - 1) & ~(n - 1))
  227. X#define BLOCKSIZE ((size_t) 4096)
  228. X
  229. Xextern void *ealloc(size_t n) {
  230. X    extern void *malloc(size_t);
  231. X    void *p = malloc(n);
  232. X    if (p == NULL) {
  233. X        perror("malloc");
  234. X        exit(1);
  235. X    }
  236. X    return p;
  237. X}
  238. X
  239. X/* gets a block from malloc space and places it at the head of the used-list */
  240. X
  241. Xstatic void getblock(size_t n) {
  242. X    Block *r, *p;
  243. X
  244. X    for (r = fl, p = NULL; r != NULL; p = r, r = r->n)
  245. X        if (n <= r->size)
  246. X            break;
  247. X
  248. X    if (r != NULL) {
  249. X        if (p != NULL)
  250. X            p->n = r->n;
  251. X        else
  252. X            fl = r->n;
  253. X    } else {
  254. X        r = ealloc(sizeof *r);
  255. X        r->mem = ealloc(alignto(n, BLOCKSIZE));
  256. X        r->size = alignto(n, BLOCKSIZE);
  257. X    }
  258. X
  259. X    r->used = 0;
  260. X    r->n = ul;
  261. X    ul = r;
  262. X}
  263. X
  264. X/*
  265. X   A fast single-arena allocator. Looks at the current block, and if there is not enough room,
  266. X   it goes to getblock() for more. "ul" stands for "used list", and the head of the list is the
  267. X   current block.
  268. X*/
  269. X
  270. Xextern void *alloc(size_t n) {
  271. X    char *ret;
  272. X        n = alignto(n, sizeof (size_t)); /* a good guess about how to align data? */
  273. X    if (ul == NULL || n + ul->used >= ul->size)
  274. X        getblock(n);
  275. X    ret = ul->mem + ul->used;
  276. X    ul->used += n;
  277. X    return ret;
  278. X}
  279. X
  280. X/*
  281. X   Frees memory from nalloc space by putting it on the freelist. Returns free blocks to the
  282. X   system, retaining at least MAXMEM bytes worth of blocks for nalloc.
  283. X*/
  284. X
  285. X#define MAXMEM 500000
  286. X
  287. Xextern void afree() {
  288. X    Block *r;
  289. X    size_t count;
  290. X    if (ul == NULL)
  291. X        return;
  292. X    for (r = ul; r->n != NULL; r = r->n)
  293. X        ;
  294. X    r->n = fl;
  295. X    fl = ul;
  296. X    ul = NULL;
  297. X    for (r = fl, count = r->size; r->n != NULL; r = r->n, count += r->size) {
  298. X        if (count >= MAXMEM) {
  299. X            Block *tmp = r;
  300. X            r = r->n;
  301. X            tmp->n = NULL;        /* terminate the freelist */
  302. X            while (r != NULL) {    /* free memory off the tail of the freelist */
  303. X                tmp = r->n;
  304. X                free(r->mem);
  305. X                free(r);
  306. X                r = tmp;
  307. X            }
  308. X        return;
  309. X        }
  310. X    }
  311. X}
  312. END_OF_FILE
  313.   if test 2113 -ne `wc -c <'alloc.c'`; then
  314.     echo shar: \"'alloc.c'\" unpacked with wrong size!
  315.   fi
  316.   # end of 'alloc.c'
  317. fi
  318. if test -f 'dpy.c' -a "${1}" != "-c" ; then 
  319.   echo shar: Will not clobber existing file \"'dpy.c'\"
  320. else
  321.   echo shar: Extracting \"'dpy.c'\" \(680 characters\)
  322.   sed "s/^X//" >'dpy.c' <<'END_OF_FILE'
  323. X#include "pico.h"
  324. X
  325. X#ifdef sgi
  326. X#include <gl/gl.h>
  327. Xstatic void initdisplay() {
  328. X    static init;
  329. X    if (!init) {
  330. X        init = 1;
  331. X        prefposition(200, 199 + DEF_X, 200, 199 + DEF_Y);
  332. X        foreground();
  333. X        winopen("pico");
  334. X        RGBmode();
  335. X        gconfig();
  336. X    }
  337. X}
  338. X
  339. X/*
  340. X   pico works with [0,0] in the top left, but sgi windows put it in
  341. X   the bottom left
  342. X*/
  343. X
  344. Xextern void display(unsigned char *data) {
  345. X    unsigned long scr[DEF_X * DEF_Y];
  346. X    int i,j;
  347. X    initdisplay();
  348. X    for (i = 0, j = DEF_X*(DEF_Y-1); i < DEF_Y*DEF_X; i++, (++j&(DEF_X-1)) || j -= 2*DEF_X)
  349. X        scr[j] = data[i] | (data[i]<<8) | (data[i]<<16);
  350. X    lrectwrite(0, 0, DEF_X - 1, DEF_Y - 1, scr);
  351. X}
  352. X#else
  353. Xextern void display(unsigned char *data) {
  354. X}
  355. X#endif
  356. END_OF_FILE
  357.   if test 680 -ne `wc -c <'dpy.c'`; then
  358.     echo shar: \"'dpy.c'\" unpacked with wrong size!
  359.   fi
  360.   # end of 'dpy.c'
  361. fi
  362. if test -f 'expr.y' -a "${1}" != "-c" ; then 
  363.   echo shar: Will not clobber existing file \"'expr.y'\"
  364. else
  365.   echo shar: Extracting \"'expr.y'\" \(4275 characters\)
  366.   sed "s/^X//" >'expr.y' <<'END_OF_FILE'
  367. X%{
  368. X#include <stdlib.h>
  369. X#include <ctype.h>
  370. X#include <stdio.h>
  371. X#include "pico.h"
  372. X
  373. Xstatic int yylex(void);
  374. Xstatic void yyerror(char *);
  375. X
  376. Xstatic lastnum;
  377. Xstatic char lastname[1024];
  378. X%}
  379. X
  380. X%union {
  381. X    Tree *node;
  382. X    int num;
  383. X}
  384. X
  385. X%term ANDAND OROR EQ NE LE GE LL RR ICON NAME
  386. X%type <node> cmd expr ss or xor and eq rel shift
  387. X%type <node> plus times factor coord
  388. X%type <num> file
  389. X
  390. X%%
  391. X
  392. Xpico    : /* empty */        { tree = NULL; YYACCEPT; }
  393. X    | '\n'            { tree = NULL; YYACCEPT; }
  394. X    | error '\n'        { tree = NULL; YYABORT; }
  395. X    | cmd '\n'        { tree = $1; YYACCEPT; }
  396. X
  397. Xcmd    : expr
  398. X    | 'w' NAME        { $$ = mkun(Write,lastname); }
  399. X    | 'r' NAME        { $$ = mkun(Read,lastname); }
  400. X    | 'f'            { $$ = mkempty(Files); }
  401. X    | 'u'            { $$ = mkempty(Undo); }
  402. X    | 'q'            { $$ = mkempty(Quit); }
  403. X
  404. Xexpr    : ss
  405. X    | ss '?' expr ':' expr    { $$ = mkCond($1,$3,$5); }
  406. X
  407. Xss    : or
  408. X    | ss ANDAND or        { $$ = mk(Andalso,$1,$3); }
  409. X    | ss OROR or        { $$ = mk(Orelse,$1,$3); }
  410. X
  411. Xor    : xor
  412. X    | or '|' xor        { $$ = mk(Or,$1,$3); }
  413. X
  414. Xxor    : and
  415. X    | xor '^' and        { $$ = mk(Xor,$1,$3); }
  416. X
  417. Xand    : eq
  418. X    | and '&' eq        { $$ = mk(And,$1,$3); }
  419. X
  420. Xeq    : rel
  421. X    | eq EQ rel        { $$ = mk(Eq,$1,$3); }
  422. X    | eq NE rel        { $$ = mk(Ne,$1,$3); }
  423. X
  424. Xrel    : shift
  425. X    | rel '<' shift        { $$ = mk(Lt,$1,$3); }
  426. X    | rel '>' shift        { $$ = mk(Gt,$1,$3); }
  427. X    | rel LE shift        { $$ = mk(Ge,$1,$3); }
  428. X    | rel GE shift        { $$ = mk(Le,$1,$3); }
  429. X
  430. Xshift    : plus
  431. X    | shift LL plus        { $$ = mk(Ll,$1,$3); }
  432. X    | shift RR plus        { $$ = mk(Rr,$1,$3); }
  433. X
  434. X
  435. Xplus    : times
  436. X    | plus '+' times    { $$ = mk(Add,$1,$3); }
  437. X    | plus '-' times    { $$ = mk(Sub,$1,$3); }
  438. X
  439. Xtimes    : factor
  440. X    | times '*' factor    { $$ = mk(Mult,$1,$3); }
  441. X    | times '/' factor    { $$ = mk(Div,$1,$3); }
  442. X    | times '%' factor    { $$ = mk(Mod,$1,$3); }
  443. X
  444. Xfactor    : 'x'            { $$ = mkempty(Xcoord); }
  445. X    | 'y'            { $$ = mkempty(Ycoord); }
  446. X    | ICON            { $$ = mkNum(lastnum); }
  447. X    | '+' factor        { $$ = $2; }
  448. X    | '-' factor        { $$ = mkun(Neg,$2); }
  449. X    | '!' factor        { $$ = mkun(Bang,$2); }
  450. X    | '~' factor        { $$ = mkun(Not,$2); }
  451. X    | file coord        { $$ = mkCoord($1,$2); }
  452. X    | '(' expr ')'        { $$ = $2; }
  453. X
  454. Xfile    : NAME            { $$ = findfile(lastname); }
  455. X    | '$' ICON        { $$ = lastnum + 1; }
  456. X
  457. Xcoord    : /* nada */        { $$ = NULL; }
  458. X    | '[' expr ',' expr ']' { $$ = mk(Add,$2,mk(Mult,$4,mkNum(DEF_Y))); }
  459. X%%
  460. X
  461. Xstatic int yylex() {
  462. X    char *l;
  463. X    int c;
  464. X    while ((c = getchar()) == ' ' || c == '\t')
  465. X        ;
  466. X    switch (c) {
  467. X    case EOF:
  468. X        saw_eof = 1;
  469. X        return 0;
  470. X    case '\n':
  471. X    case '?': case ':':
  472. X    case '-': case '+':
  473. X    case '*': case '/': case '%':
  474. X    case '~': case '^':
  475. X    case '(': case ')':
  476. X    case '[': case ']':
  477. X    case ',': case '$':
  478. X        return c;
  479. X    case '&':
  480. X        if ((c = getchar()) == '&')
  481. X            return ANDAND;
  482. X        ungetc(c,stdin);
  483. X        return '&';
  484. X    case '|':
  485. X        if ((c = getchar()) == '|')
  486. X            return OROR;
  487. X        ungetc(c,stdin);
  488. X        return '|';
  489. X    case '>':
  490. X        if ((c = getchar()) == '>')
  491. X            return RR;
  492. X        else if (c == '=')
  493. X            return GE;
  494. X        ungetc(c,stdin);
  495. X        return '>';
  496. X    case '<':
  497. X        if ((c = getchar()) == '<')
  498. X            return LL;
  499. X        else if (c == '=')
  500. X            return LE;
  501. X        ungetc(c,stdin);
  502. X        return '<';
  503. X    case '=':
  504. X        if ((c = getchar()) == '=')
  505. X            return EQ;
  506. X        ungetc(c,stdin);
  507. X        return '=';
  508. X    case '!':
  509. X        if ((c = getchar()) == '=')
  510. X            return NE;
  511. X        ungetc(c,stdin);
  512. X        return '!';
  513. X    case '\"':
  514. X        l = lastname;
  515. X        while ((c = getchar()) != '\"' && c != '\n' && c != EOF)
  516. X            *l++ = c;
  517. X        if (c != '\"')
  518. X            ungetc(c,stdin);
  519. X        *l = '\0';
  520. X        return NAME;
  521. X    default:
  522. X        if (isdigit(c)) {
  523. X            lastnum = c - '0';
  524. X            while (isdigit(c = getchar()))
  525. X                lastnum = (lastnum * 10) + (c - '0');
  526. X            ungetc(c,stdin);
  527. X            return ICON;
  528. X        } else {
  529. X            l = lastname;
  530. X            while (1) {
  531. X                *l++ = c;
  532. X                switch (c = getchar()) {
  533. X                case EOF: case ' ': case '\t': case '\n':
  534. X                case '?': case ':': case '-': case '+':
  535. X                case '*': case '/': case '%':
  536. X                case '~': case '^': case '(': case ')':
  537. X                case '<': case '>': case '[': case ']':
  538. X                case '&': case '|': case '=': case '!':
  539. X                case '\"': case ',':
  540. X                    ungetc(c,stdin);
  541. X                    if (l == lastname + 1)
  542. X                        switch (*lastname) {
  543. X                        case 'x': case 'y': case 'u':
  544. X                        case 'f': case 'q': case 'w':
  545. X                        case 'r':
  546. X                            return *lastname;
  547. X                        case 'X':
  548. X                            lastnum = DEF_X;
  549. X                            return ICON;
  550. X                        case 'Y':
  551. X                            lastnum = DEF_Y;
  552. X                            return ICON;
  553. X                        case 'Z':
  554. X                            lastnum = 255;
  555. X                            return ICON;
  556. X                        }
  557. X                    *l = '\0';
  558. X                    return NAME;
  559. X                }
  560. X            }
  561. X        }
  562. X    }
  563. X}
  564. X
  565. Xstatic void yyerror(char *err) {
  566. X    fprintf(stderr, "%s\n", err);
  567. X}
  568. END_OF_FILE
  569.   if test 4275 -ne `wc -c <'expr.y'`; then
  570.     echo shar: \"'expr.y'\" unpacked with wrong size!
  571.   fi
  572.   # end of 'expr.y'
  573. fi
  574. if test -f 'file.c' -a "${1}" != "-c" ; then 
  575.   echo shar: Will not clobber existing file \"'file.c'\"
  576. else
  577.   echo shar: Extracting \"'file.c'\" \(2097 characters\)
  578.   sed "s/^X//" >'file.c' <<'END_OF_FILE'
  579. X#include <string.h>
  580. X#include <ctype.h>
  581. X#include "pico.h"
  582. X
  583. Xint nfiles = 2;
  584. X
  585. XBuf buf[NFILES];
  586. X
  587. Xextern int findfile(char *name) {
  588. X    int i;
  589. X    if (strcmp(name, "old") == 0)
  590. X        return 1;
  591. X    for (i = 2; i < nfiles; i++)
  592. X        if (strcmp(buf[i].name, name) == 0)
  593. X            return i;
  594. X    return -1;
  595. X}
  596. X
  597. Xextern void showfiles() {
  598. X    int i;
  599. X    if (nfiles == 2) {
  600. X        fprintf(stderr, "no files open\n");
  601. X    } else {
  602. X        for (i = 2; i < nfiles; i++)
  603. X            printf("$%d = %s\n", i - 1, buf[i].name);
  604. X    }
  605. X}
  606. X
  607. Xextern void writefile(char *name) {
  608. X    int f = findfile(name);
  609. X    FILE *fp = fopen(name, "w");
  610. X    if (fp == NULL) {
  611. X        perror(name);
  612. X        return;
  613. X    }
  614. X    fprintf(fp, "P5 %d %d 255\n", DEF_X, DEF_Y);
  615. X    fwrite(buf[0].data, 1, DEF_X * DEF_Y, fp);
  616. X    fclose(fp);
  617. X    if (f < 0) {
  618. X        if (nfiles >= NFILES)
  619. X            return;
  620. X        f = nfiles++;
  621. X        buf[f].name = strdup(name);
  622. X        buf[f].data = ealloc(DEF_X * DEF_Y);
  623. X    }
  624. X    memcpy(buf[f].data, buf[0].data, DEF_X * DEF_Y);
  625. X}
  626. X
  627. X#define failif(x,y) if (x) {y; f = -1; goto fail;}
  628. X#define next fgetc(fp)
  629. X
  630. Xextern int readfile(char *name) {
  631. X    FILE *fp = fopen(name, "r");
  632. X    int c,i,f = findfile(name);
  633. X    failif(f > 0 && nfiles >= NFILES, fprintf(stderr, "too many open files\n"))
  634. X    failif(fp == NULL, perror(name))
  635. X    failif(next != 'P' || next != '5', fprintf(stderr, "%s: bad magic number\n", name))
  636. X    while (isspace(c = next))
  637. X        ;
  638. X    failif(!isdigit(c), fprintf(stderr, "%s: expected a decimal number, saw: %c\n", name, c))
  639. X    for (i = c - '0'; isdigit(c = next); i = i*10 + c-'0')
  640. X        ;
  641. X    failif(i != DEF_X, fprintf(stderr, "%s: expected an x-coordinate of %d\n", name, DEF_X))
  642. X    while (isspace(c))
  643. X        c = next;
  644. X    for (i = c - '0'; isdigit(c = next); i = i*10 + c-'0')
  645. X        ;
  646. X    failif(i != DEF_Y, fprintf(stderr, "%s: expected a y-coordinate of %d\n", name, DEF_Y))
  647. X    while (isspace(c))
  648. X        c = next;
  649. X    for (i = c - '0'; isdigit(c = next); i = i*10 + c-'0')
  650. X        ;
  651. X    failif(i != 255, fprintf(stderr, "%s: expected a grey scale of 255, saw\n", name, i))
  652. X    if (!isspace(c))
  653. X        ungetc(c,fp);
  654. X    if (f < 0) {
  655. X        f = nfiles++;
  656. X        buf[f].name = strdup(name);
  657. X        buf[f].data = ealloc(DEF_X * DEF_Y);
  658. X    }
  659. X    fread(buf[f].data, 1, DEF_X * DEF_Y, fp);
  660. Xfail:
  661. X    fclose(fp);
  662. X    return f;
  663. X}
  664. END_OF_FILE
  665.   if test 2097 -ne `wc -c <'file.c'`; then
  666.     echo shar: \"'file.c'\" unpacked with wrong size!
  667.   fi
  668.   # end of 'file.c'
  669. fi
  670. if test -f 'gen.c' -a "${1}" != "-c" ; then 
  671.   echo shar: Will not clobber existing file \"'gen.c'\"
  672. else
  673.   echo shar: Extracting \"'gen.c'\" \(67 characters\)
  674.   sed "s/^X//" >'gen.c' <<'END_OF_FILE'
  675. X#ifdef sgi
  676. X#include "mipsgen.c"
  677. X#else
  678. X#include "sparcgen.c"
  679. X#endif
  680. END_OF_FILE
  681.   if test 67 -ne `wc -c <'gen.c'`; then
  682.     echo shar: \"'gen.c'\" unpacked with wrong size!
  683.   fi
  684.   # end of 'gen.c'
  685. fi
  686. if test -f 'main.c' -a "${1}" != "-c" ; then 
  687.   echo shar: Will not clobber existing file \"'main.c'\"
  688. else
  689.   echo shar: Extracting \"'main.c'\" \(1507 characters\)
  690.   sed "s/^X//" >'main.c' <<'END_OF_FILE'
  691. X#include <setjmp.h>
  692. X#include <string.h>
  693. X#include "pico.h"
  694. X
  695. Xint debug, saw_eof;
  696. XTree *tree;
  697. X
  698. Xstatic void run(Tree *t);
  699. X
  700. Xstatic disp = 1;
  701. Xstatic jmp_buf jb;
  702. X
  703. Xextern int main(int argc, char *argv[]) {
  704. X    extern int optind;
  705. X    int c, err = 0;
  706. X
  707. X    while ((c = getopt(argc, argv, "dn")) != -1)
  708. X        if (c == 'd')
  709. X            debug = 1;
  710. X        else if (c == 'n')
  711. X            disp = 0;
  712. X        else
  713. X            err = 1;
  714. X    if (err || argc - optind != 0) {
  715. X        fprintf(stderr, "usage: pico [-nd]");
  716. X        exit(1);
  717. X    }
  718. X    buf[0].data = ealloc(DEF_X * DEF_Y);
  719. X    buf[1].data = ealloc(DEF_X * DEF_Y);
  720. X    setjmp(jb);
  721. X    while (1) {
  722. X        fprintf(stderr, "> ");
  723. X        fflush(stderr);
  724. X        yyparse();
  725. X        if (saw_eof)
  726. X            return 0;
  727. X        if (tree != NULL)
  728. X            run(tree);
  729. X        afree();
  730. X    }
  731. X}
  732. X
  733. X#define swap(x,y) {\
  734. X    unsigned char *tmp = x;\
  735. X    x = y;\
  736. X    y = tmp;\
  737. X}
  738. X
  739. Xstatic void run(Tree *t) {
  740. X    int f;
  741. X    switch (t->t) {
  742. X    case Quit:
  743. X        exit(0);
  744. X    case Undo:
  745. X        swap(buf[0].data, buf[1].data);
  746. X        if (disp)
  747. X            display(buf[0].data);
  748. X        break;
  749. X    case Read:
  750. X        if ((f = readfile(t->kids[0])) > 0) {
  751. X            swap(buf[0].data, buf[1].data);
  752. X            memcpy(buf[0].data, buf[f].data, DEF_X * DEF_Y);
  753. X            if (disp)
  754. X                display(buf[0].data);
  755. X        }
  756. X        break;
  757. X    case Write:
  758. X        writefile(t->kids[0]);
  759. X        break;
  760. X    case Files:
  761. X        showfiles();
  762. X        break;
  763. X    default:
  764. X        swap(buf[0].data, buf[1].data);
  765. X        compile(t);
  766. X#ifdef sgi
  767. X        if (debug)
  768. X            system("dis pico.out");
  769. X#else
  770. X        if (debug)
  771. X            system("echo ',-1?' | adb " DUMPFILE);
  772. X#endif
  773. X        if (disp)
  774. X            display(buf[0].data);
  775. X        break;
  776. X    }
  777. X}
  778. X
  779. Xextern void error(char *s) {
  780. X    fprintf(stderr, "%s\n", s);
  781. X    longjmp(jb,1);
  782. X}
  783. END_OF_FILE
  784.   if test 1507 -ne `wc -c <'main.c'`; then
  785.     echo shar: \"'main.c'\" unpacked with wrong size!
  786.   fi
  787.   # end of 'main.c'
  788. fi
  789. if test -f 'mipsgen.c' -a "${1}" != "-c" ; then 
  790.   echo shar: Will not clobber existing file \"'mipsgen.c'\"
  791. else
  792.   echo shar: Extracting \"'mipsgen.c'\" \(9124 characters\)
  793.   sed "s/^X//" >'mipsgen.c' <<'END_OF_FILE'
  794. X#include <sys/cachectl.h>
  795. X#include <a.out.h>
  796. X#include <unistd.h>
  797. X#include <string.h>
  798. X#include "pico.h"
  799. X
  800. Xtypedef unsigned long Inst;
  801. X
  802. Xstatic void gen(Tree *t);
  803. Xstatic void binop(Tree *t, int s1, int s2, int d);
  804. Xstatic void binconst(Tree *t, int s1, int s2, int d);
  805. Xstatic void dodump(Inst *, int);
  806. Xstatic void clearregs(void);
  807. Xstatic void freereg(int);
  808. Xstatic int findreg(void);
  809. X
  810. Xstatic Inst *code;
  811. Xstatic boolean, last = 8, regs[8], spp, sppmax, result;
  812. X
  813. X#define zero    0
  814. X#define tmp    1
  815. X#define base    4    /* first arg */
  816. X#define offset    5    /* second arg */
  817. X#define rx    16    /* first saved reg */
  818. X#define ry    17
  819. X#define sp    29
  820. X#define ra    31
  821. X
  822. X#define RTYPE(a,b,c,d)    (d|(c<<11)|(b<<16)|(a<<21))
  823. X#define STYPE(a,b,c,d)    (d|(c<<11)|(b<<6)|(a<<16))
  824. X#define ITYPE(a,b,c,d)    ((d<<26)|(a<<21)|(b&0xffff)|(c<<16))
  825. X
  826. X#define _ADDU(a,b,c)    *code++ = RTYPE(a,b,c,041)
  827. X#define _SUBU(a,b,c)    *code++ = RTYPE(a,b,c,043)
  828. X#define _MULTU(a,b)    *code++ = RTYPE(a,b,0,031)
  829. X#define _DIVU(a,b)    *code++ = RTYPE(a,b,0,033)
  830. X#define _MFLO(a)    *code++ = RTYPE(0,0,a,022)
  831. X#define _MFHI(a)    *code++ = RTYPE(0,0,a,020)
  832. X#define _SLTU(a,b,c)    *code++ = RTYPE(a,b,c,053)
  833. X#define _XOR(a,b,c)    *code++ = RTYPE(a,b,c,046)
  834. X#define _OR(a,b,c)    *code++ = RTYPE(a,b,c,045)
  835. X#define _NOR(a,b,c)    *code++ = RTYPE(a,b,c,047)
  836. X#define _AND(a,b,c)    *code++ = RTYPE(a,b,c,044)
  837. X#define _ANDI(a,b,c)    *code++ = ITYPE(a,b,c,014)
  838. X#define _XORI(a,b,c)    *code++ = ITYPE(a,b,c,016)
  839. X#define _ORI(a,b,c)    *code++ = ITYPE(a,b,c,015)
  840. X#define _ADDIU(a,b,c)    *code++ = ITYPE(a,b,c,011)
  841. X#define _SLTIU(a,b,c)    *code++ = ITYPE(a,b,c,013)
  842. X#define _LBU(a,b,c)    *code++ = ITYPE(b,c,a,044)
  843. X#define _SB(a,b,c)    *code++ = ITYPE(b,c,a,050)
  844. X#define _LW(a,b,c)    *code++ = ITYPE(b,c,a,043)
  845. X#define _SW(a,b,c)    *code++ = ITYPE(b,c,a,053)
  846. X#define _LUI(a,b)    *code++ = ITYPE(0,b,a,017)
  847. X#define _BNE(a,b,c)          ITYPE(b,c,a,005)
  848. X#define _BEQ(a,b,c)          ITYPE(b,c,a,004)
  849. X#define _JR(a)        *code++ = RTYPE(a,0,0,010)
  850. X#define _SLL(a,b,c)    *code++ = STYPE(a,b,c,000)
  851. X#define _SRL(a,b,c)    *code++ = STYPE(a,b,c,002)
  852. X#define _SRLV(a,b,c)    *code++ = RTYPE(a,b,c,006)
  853. X#define _SLLV(a,b,c)    *code++ = RTYPE(b,a,c,004)
  854. X#define _SRLV(a,b,c)    *code++ = RTYPE(a,b,c,006)
  855. X#define _NOP        *code++ = 0x0
  856. X
  857. X#define _PUSH(a) {\
  858. X    _SW(a,sp,spp);\
  859. X    spp += 4;\
  860. X    if (spp > sppmax)\
  861. X        sppmax = spp;\
  862. X}
  863. X
  864. X#define _POP(a) {\
  865. X    spp -= 4;\
  866. X    _LW(a,sp,spp);\
  867. X}
  868. X
  869. Xstatic void loadimm(int i, int j) {
  870. X    if (j < 0 && j >= -32768) {
  871. X        _ADDIU(zero,j,i);
  872. X    } else if ((Inst) j > 65535) {
  873. X        Inst k = (Inst) j >> 16;
  874. X        Inst l = (Inst) j & 65535;
  875. X        _LUI(i,k);
  876. X        if (l != 0)
  877. X            _ORI(i,l,i);
  878. X    } else {
  879. X        _ORI(zero,((Inst)j),i);
  880. X    }
  881. X}
  882. X
  883. Xextern void compile(Tree *t) {
  884. X    Inst prog[1024], *remem1, *remem2;
  885. X    void (*progp)() = (void (*)()) prog;
  886. X    code = prog;
  887. X    clearregs();
  888. X    last = findreg();
  889. X    code = prog;
  890. X    _ADDIU(sp,0,sp); /* value is or'ed in later */
  891. X    _PUSH(rx);
  892. X    _PUSH(ry);
  893. X    loadimm(ry,DEF_Y-1);
  894. X    remem1 = code;
  895. X    loadimm(rx,DEF_X-1);
  896. X    remem2 = code;
  897. X    gen(t);
  898. X    _ADDU(base,offset,tmp);
  899. X    _SB(result,tmp,0);
  900. X    _ADDIU(offset,-1,offset);
  901. X    *code = _BNE(zero,rx,remem2-code-1); code++;
  902. X    _ADDIU(rx,-1,rx);
  903. X    *code = _BNE(zero,ry,remem1-code-1); code++;
  904. X    _ADDIU(ry,-1,ry);
  905. X    _POP(ry);
  906. X    _POP(rx);
  907. X    _JR(ra);
  908. X    _ADDIU(sp,sppmax,sp);
  909. X    *prog |= (-sppmax)&0xffff;
  910. X    dodump(prog, (code - prog) * sizeof (Inst));
  911. X    cacheflush(prog, sizeof prog, ICACHE);
  912. X    progp(buf[0].data, (DEF_X*DEF_Y) - 1);
  913. X}
  914. X
  915. Xstatic void gen(Tree *t) {
  916. X    Inst *remem;
  917. X    int i, saved, b1, b2;
  918. X    switch (t->t) {
  919. X    case Num:
  920. X        if (t->i == 0) {
  921. X            result = zero;
  922. X            boolean = 1;
  923. X        } else {
  924. X            loadimm(result = last, t->i);
  925. X            boolean = !(t->i & ~1);
  926. X        }
  927. X        break;
  928. X    case Xcoord:
  929. X        result = rx;
  930. X        boolean = 0;
  931. X        break;
  932. X    case Ycoord:
  933. X        result = ry;
  934. X        boolean = 0;
  935. X        break;
  936. X    case Bang:
  937. X        gen(t->kids[0]);
  938. X        _SLTIU(result,1,last);
  939. X        result = last;
  940. X        boolean = 1;
  941. X        break;
  942. X    case Not:
  943. X        gen(t->kids[0]);
  944. X        _NOR(result,0,last);
  945. X        result = last;
  946. X        boolean = 0;
  947. X        break;
  948. X    case Neg:
  949. X        gen(t->kids[0]);
  950. X        _SUBU(zero,result,last);
  951. X        result = last;
  952. X        boolean = 0;
  953. X        break;
  954. X    case Cond:
  955. X        gen(t->kids[0]);        /* test */
  956. X        remem = code;
  957. X        *code++ = _BEQ(zero,result,0);
  958. X        _NOP;
  959. X        gen(t->kids[1]);        /* iftrue */
  960. X        b1 = boolean;
  961. X        if (result != last)
  962. X            _ADDU(result,zero,last);
  963. X        *remem |= code - remem;
  964. X        remem = code - 1;
  965. X        *code = code[-1];
  966. X        code[-1] = _BEQ(zero,zero,0);    /* fill delay slot */
  967. X        code++;
  968. X        gen(t->kids[2]);        /* iffalse */
  969. X        b2 = boolean;
  970. X        if (result != last)
  971. X            _ADDU(result,zero,last);
  972. X        result = last;
  973. X        boolean = (b1 & b2);
  974. X        *remem |= code - remem - 1;
  975. X        break;
  976. X    case Andalso:
  977. X    case Orelse:
  978. X        gen(t->kids[0]);
  979. X        b1 = boolean;
  980. X        if (result != last)
  981. X            _ADDU(result,zero,last);
  982. X        saved = last;
  983. X        remem = code;
  984. X        if (t->t == Andalso)
  985. X            *code++ = _BEQ(zero,last,0);
  986. X        else
  987. X            *code++ = _BNE(zero,last,0);
  988. X        _NOP;
  989. X        gen(t->kids[1]);
  990. X        b2 = boolean;
  991. X        if (result != saved)
  992. X            _ADDU(result,zero,saved);
  993. X        *remem |= code - remem - 1;
  994. X        if (!(b1&b2))
  995. X            _SLTU(zero,last,last);        /* "normalize" expr to {0,1} */
  996. X        result = saved;
  997. X        boolean = 1;
  998. X        break;
  999. X    case Coordpair:
  1000. X        if (t->i > nfiles || t->i < 0)
  1001. X            error("no such buffer");
  1002. X        if (t->kids[0] != NULL) {
  1003. X            gen(t->kids[0]);
  1004. X            i = last;
  1005. X        } else
  1006. X            i = offset;
  1007. X        loadimm(tmp,(int)buf[t->i].data);
  1008. X        _ADDU(tmp,i,last);
  1009. X        _LBU(last,last,0);
  1010. X        _NOP;
  1011. X        result = last;
  1012. X        boolean = 0;
  1013. X        break;
  1014. X    default:
  1015. X        gen(t->kids[0]);
  1016. X        saved = result;
  1017. X        if (((Tree *)t->kids[1])->t == Num && (i = ((Tree *)t->kids[1])->i) < 32768 && i > -32768) {
  1018. X            binconst(t,result,i,last);
  1019. X        } else {
  1020. X            if (saved != rx && saved != ry && (last = findreg()) == -1) {
  1021. X                last = saved;
  1022. X                saved = -1;
  1023. X                _PUSH(last);
  1024. X            }
  1025. X            gen(t->kids[1]);
  1026. X            if (saved == -1) {
  1027. X                _POP(tmp);
  1028. X                _NOP;
  1029. X                binop(t,tmp,result,last);
  1030. X            } else {
  1031. X                binop(t,saved,result,last);
  1032. X                if (saved != rx && saved != ry)
  1033. X                    freereg(saved);
  1034. X            }
  1035. X        }
  1036. X        result = last;
  1037. X    }
  1038. X}
  1039. X
  1040. Xstatic void binop(Tree *t, int s1, int s2, int d) {
  1041. X    boolean = 0;
  1042. X    switch (t->t) {
  1043. X    default:
  1044. X        error("not a binop in binop!");
  1045. X    case Add:
  1046. X        _ADDU(s1,s2,d);
  1047. X        break;
  1048. X    case Sub:
  1049. X        _SUBU(s1,s2,d);
  1050. X        break;
  1051. X    case Mult:
  1052. X        _MULTU(s1,s2);
  1053. X        _MFLO(d);
  1054. X        break;
  1055. X    case Div:
  1056. X        _DIVU(s1,s2);
  1057. X        _MFLO(d);
  1058. X        break;
  1059. X    case Mod:
  1060. X        _DIVU(s1,s2);
  1061. X        _MFHI(d);
  1062. X        break;
  1063. X    case Gt:
  1064. X        _SLTU(s2,s1,d);
  1065. X        boolean = 1;
  1066. X        break;
  1067. X    case Lt:
  1068. X        _SLTU(s1,s2,d);
  1069. X        boolean = 1;
  1070. X        break;
  1071. X    case Ge:
  1072. X        _SLTU(s1,s2,d);
  1073. X        _XORI(d,1,d);
  1074. X        boolean = 1;
  1075. X        break;
  1076. X    case Le:
  1077. X        _SLTU(s2,s1,d);
  1078. X        _XORI(d,1,d);
  1079. X        boolean = 1;
  1080. X        break;
  1081. X    case Eq:
  1082. X        _XOR(s1,s2,d);
  1083. X        _SLTIU(d,1,d);
  1084. X        boolean = 1;
  1085. X        break;
  1086. X    case Ne:
  1087. X        _XOR(s1,s2,d);
  1088. X        _SLTIU(d,0,d);
  1089. X        boolean = 1;
  1090. X        break;
  1091. X    case Xor:
  1092. X        _XOR(s1,s2,d);
  1093. X        break;
  1094. X    case And:
  1095. X        _AND(s1,s2,d);
  1096. X        break;
  1097. X    case Or:
  1098. X        _OR(s1,s2,d);
  1099. X        break;
  1100. X    case Ll:
  1101. X        _SLLV(s1,s2,d);
  1102. X        break;
  1103. X    case Rr:
  1104. X        _SRLV(s1,s2,d);
  1105. X        break;
  1106. X    }
  1107. X}
  1108. X
  1109. Xstatic void binconst(Tree *t, int s1, int s2, int d) {
  1110. X    int shift;
  1111. X    boolean = 0;
  1112. X    switch (t->t) {
  1113. X    default:
  1114. X        error("not a binop in binconst!");
  1115. X    case Add:
  1116. X        _ADDIU(s1,s2,d);
  1117. X        break;
  1118. X    case Sub:
  1119. X        _ADDIU(s1,-s2,d);
  1120. X        break;
  1121. X    case Mult:
  1122. X    case Div:
  1123. X        if (s2 < 0 || s2 & (s2 - 1) != 0) {
  1124. X            loadimm(tmp,s2);
  1125. X            if (t->t == Mult)
  1126. X                _MULTU(s1,tmp);
  1127. X            else
  1128. X                _DIVU(s1,tmp);
  1129. X        _MFLO(d);
  1130. X        } else {
  1131. X            for (shift = 0; s2 != 0; shift++, s2 >>= 1)
  1132. X                ;
  1133. X            if (shift == 0) {
  1134. X                if (t->t == Mult)
  1135. X                    loadimm(d,0);
  1136. X                else
  1137. X                    error("division by zero");
  1138. X                return;
  1139. X            } else if (t->t == Mult) {
  1140. X                _SLL(s1,--shift,d);
  1141. X            } else {
  1142. X                _SRL(s1,--shift,d);
  1143. X            }
  1144. X        }
  1145. X        break;
  1146. X    case Mod:
  1147. X        loadimm(tmp,s2);
  1148. X        _DIVU(s1,tmp);
  1149. X        _MFHI(d);
  1150. X        break;
  1151. X    case Gt:
  1152. X        if (s2 != 0) {
  1153. X            loadimm(tmp,s2);
  1154. X            _SLTU(tmp,s1,d);
  1155. X        } else
  1156. X            _SLTU(zero,s1,d);
  1157. X        boolean = 1;
  1158. X        break;
  1159. X    case Lt:
  1160. X        _SLTIU(s1,s2,d);
  1161. X        boolean = 1;
  1162. X        break;
  1163. X    case Ge:
  1164. X        _SLTIU(s1,s2,d);
  1165. X        _XORI(d,1,d);
  1166. X        boolean = 1;
  1167. X        break;
  1168. X    case Le:
  1169. X        if (s2 != 0) {
  1170. X            loadimm(tmp,s2);
  1171. X            _SLTU(tmp,s1,d);
  1172. X        } else
  1173. X            _SLTU(zero,s1,d);
  1174. X        _XORI(d,1,d);
  1175. X        boolean = 1;
  1176. X        break;
  1177. X    case Eq:
  1178. X        if (s2 != 0) {
  1179. X            _XORI(s1,s2,d);
  1180. X            _SLTIU(d,1,d);
  1181. X        } else
  1182. X            _SLTIU(s1,1,d);
  1183. X        boolean = 1;
  1184. X        break;
  1185. X    case Ne:
  1186. X        if (s2 != 0) {
  1187. X            _XORI(s1,s2,d);
  1188. X            _SLTIU(d,0,d);
  1189. X        } else
  1190. X            _SLTIU(s1,0,d);
  1191. X        boolean = 1;
  1192. X        break;
  1193. X    case Xor:
  1194. X        _XORI(s1,s2,d);
  1195. X        break;
  1196. X    case And:
  1197. X        _ANDI(s1,s2,d);
  1198. X        break;
  1199. X    case Or:
  1200. X        _ORI(s1,s2,d);
  1201. X        break;
  1202. X    case Ll:
  1203. X        _SLL(s1,s2,d);
  1204. X        break;
  1205. X    case Rr:
  1206. X        _SRL(s1,s2,d);
  1207. X        break;
  1208. X    }
  1209. X}
  1210. X
  1211. Xstatic void dodump(Inst *prog, int size) {
  1212. X    if (debug) {
  1213. X        struct filehdr f;
  1214. X        struct scnhdr s;
  1215. X        int fd = creat(DUMPFILE, 0644);
  1216. X        if (fd < 0) {
  1217. X            perror(DUMPFILE);
  1218. X            exit(1);
  1219. X        }
  1220. X        f.f_magic = MIPSEBMAGIC;
  1221. X        f.f_nscns = 1;
  1222. X        f.f_timdat = 0;
  1223. X        f.f_symptr = 0;
  1224. X        f.f_nsyms = 0;
  1225. X        f.f_opthdr = 0;
  1226. X        f.f_flags = F_RELFLG | F_EXEC | F_LNNO | F_LSYMS | F_MINMAL;
  1227. X        strcpy(s.s_name, ".text");
  1228. X        s.s_paddr = 0;
  1229. X        s.s_vaddr = 0;
  1230. X        s.s_size = size;
  1231. X        s.s_scnptr = sizeof s + sizeof f;
  1232. X        s.s_relptr = 0;
  1233. X        s.s_lnnoptr = 0;
  1234. X        s.s_nreloc = 0;
  1235. X        s.s_nlnno = 0;
  1236. X        s.s_flags = 0;
  1237. X        write(fd, &f, sizeof f);
  1238. X        write(fd, &s, sizeof s);
  1239. X        write(fd, prog, size);
  1240. X        close(fd);
  1241. X    }
  1242. X}
  1243. X
  1244. Xstatic void clearregs() {
  1245. X    int i;
  1246. X    for (i = 0; i < 8; i++)
  1247. X        regs[i] = 0;
  1248. X}
  1249. X
  1250. Xstatic void freereg(int i) {
  1251. X    regs[i-8] = 0;
  1252. X}
  1253. X
  1254. Xstatic int findreg() {
  1255. X    int i;
  1256. X    for (i = 0; i < 8; i++)
  1257. X        if (regs[i] == 0)
  1258. X            break;
  1259. X    if (i == 8)
  1260. X        return -1;
  1261. X    regs[i] = 1;
  1262. X    return i+8;
  1263. X}
  1264. END_OF_FILE
  1265.   if test 9124 -ne `wc -c <'mipsgen.c'`; then
  1266.     echo shar: \"'mipsgen.c'\" unpacked with wrong size!
  1267.   fi
  1268.   # end of 'mipsgen.c'
  1269. fi
  1270. if test -f 'mk.c' -a "${1}" != "-c" ; then 
  1271.   echo shar: Will not clobber existing file \"'mk.c'\"
  1272. else
  1273.   echo shar: Extracting \"'mk.c'\" \(779 characters\)
  1274.   sed "s/^X//" >'mk.c' <<'END_OF_FILE'
  1275. X#include "pico.h"
  1276. X
  1277. Xextern Tree *mk(enum tree t,Tree *a,Tree *b) {
  1278. X    Tree *new = treealloc(2);
  1279. X    new->kids[0] = a;
  1280. X    new->kids[1] = b;
  1281. X    new->t = t;
  1282. X    return new;
  1283. X}
  1284. X
  1285. Xextern Tree *mkNum(int i) {
  1286. X    Tree *new = treealloc(0);
  1287. X    new->i = i;
  1288. X    new->t = Num;
  1289. X    return new;
  1290. X}
  1291. X
  1292. Xextern Tree *mkCoord(int file,Tree *coord) {
  1293. X    Tree *new = treealloc(1);
  1294. X    new->i = file;
  1295. X    new->kids[0] = coord;
  1296. X    new->t = Coordpair;
  1297. X    return new;
  1298. X}
  1299. X
  1300. Xextern Tree *mkun(enum tree t,void *a) {
  1301. X    Tree *new = treealloc(1);
  1302. X    new->kids[0] = a;
  1303. X    new->t = t;
  1304. X    return new;
  1305. X}
  1306. X
  1307. Xextern Tree *mkCond(Tree *a, Tree *b, Tree *c) {
  1308. X    Tree *new = treealloc(3);
  1309. X    new->kids[0] = a;
  1310. X    new->kids[1] = b;
  1311. X    new->kids[2] = c;
  1312. X    new->t = Cond;
  1313. X    return new;
  1314. X}
  1315. X
  1316. Xextern Tree *mkempty(enum tree t) {
  1317. X    Tree *new = treealloc(0);
  1318. X    new->t = t;
  1319. X    return new;
  1320. X}
  1321. END_OF_FILE
  1322.   if test 779 -ne `wc -c <'mk.c'`; then
  1323.     echo shar: \"'mk.c'\" unpacked with wrong size!
  1324.   fi
  1325.   # end of 'mk.c'
  1326. fi
  1327. if test -f 'nodpy.c' -a "${1}" != "-c" ; then 
  1328.   echo shar: Will not clobber existing file \"'nodpy.c'\"
  1329. else
  1330.   echo shar: Extracting \"'nodpy.c'\" \(25 characters\)
  1331.   sed "s/^X//" >'nodpy.c' <<'END_OF_FILE'
  1332. Xextern void display(){
  1333. X}
  1334. END_OF_FILE
  1335.   if test 25 -ne `wc -c <'nodpy.c'`; then
  1336.     echo shar: \"'nodpy.c'\" unpacked with wrong size!
  1337.   fi
  1338.   # end of 'nodpy.c'
  1339. fi
  1340. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  1341.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  1342. else
  1343.   echo shar: Extracting \"'patchlevel.h'\" \(79 characters\)
  1344.   sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  1345. X/*
  1346. X**   Current release information.
  1347. X*/
  1348. X#define RELEASE 1
  1349. X#define PATCHLEVEL 0
  1350. END_OF_FILE
  1351.   if test 79 -ne `wc -c <'patchlevel.h'`; then
  1352.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  1353.   fi
  1354.   # end of 'patchlevel.h'
  1355. fi
  1356. if test -f 'pico.h' -a "${1}" != "-c" ; then 
  1357.   echo shar: Will not clobber existing file \"'pico.h'\"
  1358. else
  1359.   echo shar: Extracting \"'pico.h'\" \(1431 characters\)
  1360.   sed "s/^X//" >'pico.h' <<'END_OF_FILE'
  1361. X#include <stdio.h>
  1362. X#include <stdlib.h>
  1363. X
  1364. Xenum tree {
  1365. X    Num, Id, Bang, Not, Neg, Add, Sub, Mult, Div,
  1366. X    Mod, Or, Xor, And, Eq, Ne, Andalso, Orelse, Cond,
  1367. X    Gt, Lt, Ge, Le, Ll, Rr, Xcoord, Ycoord, Coordpair,
  1368. X    Write, Read, Files, Undo, Quit
  1369. X};
  1370. X
  1371. Xtypedef struct Tree Tree;
  1372. Xtypedef struct Buf Buf;
  1373. X
  1374. Xstruct Tree {
  1375. X    enum tree t;
  1376. X    int i;
  1377. X    void *kids[3];
  1378. X};
  1379. X
  1380. Xstruct Buf {
  1381. X    char *name;
  1382. X    unsigned char *data;
  1383. X};
  1384. X
  1385. X#define DEF_X 512
  1386. X#define DEF_Y 512
  1387. X#define NFILES 128
  1388. X#define DUMPFILE "pico.out"
  1389. X
  1390. X/* main.c */
  1391. Xextern int main(int, char *[]);
  1392. Xextern void syntax_error(int);
  1393. Xextern void error(char *);
  1394. Xextern unsigned char data[];
  1395. Xextern int debug, saw_eof;
  1396. Xextern Tree *tree;
  1397. X
  1398. X/* expr.c */
  1399. Xextern Tree *expr(void);
  1400. X
  1401. X/* mk.c */
  1402. Xextern Tree *mk(enum tree,Tree *,Tree *);
  1403. Xextern Tree *mkCond(Tree *,Tree *,Tree *);
  1404. Xextern Tree *mkCoord(int,Tree *);
  1405. Xextern Tree *mkun(enum tree,void *);
  1406. Xextern Tree *mkNum(int);
  1407. Xextern Tree *mkempty(enum tree);
  1408. X
  1409. X/* gen.c */
  1410. Xextern int calc(Tree *);
  1411. Xextern void compile(Tree *);
  1412. X
  1413. X/* dpy.c */
  1414. Xextern void display(unsigned char *);
  1415. X
  1416. X/* alloc.c */
  1417. Xextern void *ealloc(size_t);
  1418. Xextern void *alloc(size_t);
  1419. Xextern void afree(void);
  1420. X#ifndef offsetof
  1421. X#define offsetof(t, m) ((size_t) &((t *)0)->m)
  1422. X#endif
  1423. X#define treealloc(x) alloc(offsetof(Tree,kids[x]));
  1424. X
  1425. X/* file.c */
  1426. Xextern int findfile(char *);
  1427. Xextern void showfiles(void);
  1428. Xextern int readfile(char *);
  1429. Xextern void writefile(char *);
  1430. Xextern Buf buf[];
  1431. Xextern int nfiles;
  1432. END_OF_FILE
  1433.   if test 1431 -ne `wc -c <'pico.h'`; then
  1434.     echo shar: \"'pico.h'\" unpacked with wrong size!
  1435.   fi
  1436.   # end of 'pico.h'
  1437. fi
  1438. if test -f 'sparcgen.c' -a "${1}" != "-c" ; then 
  1439.   echo shar: Will not clobber existing file \"'sparcgen.c'\"
  1440. else
  1441.   echo shar: Extracting \"'sparcgen.c'\" \(10714 characters\)
  1442.   sed "s/^X//" >'sparcgen.c' <<'END_OF_FILE'
  1443. X#include <sys/exec.h>
  1444. X#include <unistd.h>
  1445. X#include <string.h>
  1446. X#include "pico.h"
  1447. X
  1448. Xtypedef unsigned long Inst;
  1449. X
  1450. Xstatic void gen(Tree *t);
  1451. Xstatic void binop(Tree *t, int s1, int s2, int d);
  1452. Xstatic void binconst(Tree *t, int s1, int s2, int d);
  1453. Xstatic void dodump(Inst *, int);
  1454. Xstatic void clearregs(void);
  1455. Xstatic void freereg(int);
  1456. Xstatic int findreg(void);
  1457. Xstatic int mul(int,int), div(int,int), mod(int,int);
  1458. X
  1459. Xstatic Inst *code;
  1460. Xstatic ccset, boolean, last = 18, regs[6], spp, sppmax, result;
  1461. X
  1462. X#define zero    0
  1463. X#define tmp    1
  1464. X#define base    24    /* first arg */
  1465. X#define offset    25    /* etc. */
  1466. X#define a_mul    26
  1467. X#define a_div    27
  1468. X#define a_mod    28
  1469. X#define rx    16
  1470. X#define ry    17
  1471. X#define sp    14
  1472. X#define o0    8    /* first arg out */
  1473. X#define o1    9
  1474. X
  1475. X#define OP(rd,op,rs,i,r_or_d)    ((2<<30)|(rd<<25)|(op<<19)|(rs<<14)|(i<<13)|(r_or_d&017777))
  1476. X#define MOP(rd,op,rs,i,r_or_d)    ((3<<30)|(rd<<25)|(op<<19)|(rs<<14)|(i<<13)|(r_or_d&017777))
  1477. X#define SETHI(rd,op,imm)    ((rd<<25)|(op<<22)|(imm&017777777))
  1478. X
  1479. X#define _ADD(a,b,c)    *code++ = OP(c,000,a,0,b)
  1480. X#define _ADDcc(a,b,c)    *code++ = OP(c,020,a,0,b)
  1481. X#define _SUB(a,b,c)    *code++ = OP(c,004,a,0,b)
  1482. X#define _SUBcc(a,b,c)    *code++ = OP(c,024,a,0,b)
  1483. X#define _XOR(a,b,c)    *code++ = OP(c,003,a,0,b)
  1484. X#define _XORcc(a,b,c)    *code++ = OP(c,023,a,0,b)
  1485. X#define _OR(a,b,c)    *code++ = OP(c,002,a,0,b)
  1486. X#define _ORcc(a,b,c)    *code++ = OP(c,022,a,0,b)
  1487. X#define _AND(a,b,c)    *code++ = OP(c,001,a,0,b)
  1488. X#define _ANDcc(a,b,c)    *code++ = OP(c,021,a,0,b)
  1489. X#define _NOR(a,b,c)    *code++ = OP(c,006,a,0,b)
  1490. X#define _XORI(a,b,c)    *code++ = OP(c,003,a,1,b)
  1491. X#define _XORIcc(a,b,c)    *code++ = OP(c,023,a,1,b)
  1492. X#define _ORI(a,b,c)    *code++ = OP(c,002,a,1,b)
  1493. X#define _ORIcc(a,b,c)    *code++ = OP(c,022,a,1,b)
  1494. X#define _ADDI(a,b,c)    *code++ = OP(c,000,a,1,b)
  1495. X#define _ADDIcc(a,b,c)    *code++ = OP(c,020,a,1,b)
  1496. X#define _ANDI(a,b,c)    *code++ = OP(c,001,a,1,b)
  1497. X#define _ANDIcc(a,b,c)    *code++ = OP(c,021,a,1,b)
  1498. X#define _LBU(a,b,c)    *code++ = MOP(a,001,b,0,c)
  1499. X#define _LBIU(a,b,c)    *code++ = MOP(a,001,b,1,c)
  1500. X#define _SB(a,b,c)    *code++ = MOP(a,005,b,0,c)
  1501. X#define _SBI(a,b,c)    *code++ = MOP(a,005,b,1,c)
  1502. X#define _LW(a,b,c)    *code++ = MOP(a,000,b,0,c)
  1503. X#define _LWI(a,b,c)    *code++ = MOP(a,000,b,1,c)
  1504. X#define _SW(a,b,c)    *code++ = MOP(a,004,b,0,c)
  1505. X#define _SWI(a,b,c)    *code++ = MOP(a,004,b,1,c)
  1506. X#define _SETHI(a,b)    *code++ = SETHI(a,04,b>>10)
  1507. X#define _SLL(a,b,c)    *code++ = OP(c,045,a,0,b)
  1508. X#define _SRL(a,b,c)    *code++ = OP(c,046,a,0,b)
  1509. X#define _SLLI(a,b,c)    *code++ = OP(c,045,a,1,b)
  1510. X#define _SRLI(a,b,c)    *code++ = OP(c,046,a,1,b)
  1511. X#define _CMP(a,b)    *code++ = OP(zero,024,a,0,b)    /* _SUBcc(a,b,zero); */
  1512. X#define _CMPI(a,b)    *code++ = OP(zero,024,a,1,b)    /* _SUBIcc(a,b,zero); */
  1513. X#define _B(cond,disp)          SETHI(cond,02,disp)
  1514. X#define ALWAYS    010
  1515. X#define EQ    001
  1516. X#define NE    011
  1517. X#define GE    013
  1518. X#define LE    002
  1519. X#define GT    012
  1520. X#define LT    003
  1521. X#define _JAL(a)        *code++ = OP(15,070,a,0,zero)
  1522. X#define _SAVE(a)    *code++ = OP(sp,074,sp,1,a)
  1523. X#define _RET        *code++ = 0x81c7e008        /* jmpl        %o7+8,%g0    */
  1524. X#define _RESTORE    *code++ = 0x81e80000        /* restore     %g0,%g0,%g0    */
  1525. X#define _NOP        *code++ = SETHI(zero,04,0)
  1526. X
  1527. X#define _PUSH(a) {\
  1528. X    _SW(a,sp,spp);\
  1529. X    spp += 4;\
  1530. X    if (spp > sppmax)\
  1531. X        sppmax = spp;\
  1532. X}
  1533. X
  1534. X#define _POP(a) {\
  1535. X    spp -= 4;\
  1536. X    _LW(a,sp,spp);\
  1537. X}
  1538. X
  1539. Xstatic void loadimm(int i, int j) {
  1540. X    if (j > 0x1777 || j < 0) {
  1541. X        _SETHI(i,j);
  1542. X        _ORIcc(i,(j&01777),i);
  1543. X    } else
  1544. X        _ORIcc(zero,j,i);
  1545. X}
  1546. X
  1547. Xextern void compile(Tree *t) {
  1548. X    Inst prog[1024], *remem1, *remem2;
  1549. X    void (*progp)() = (void (*)()) prog;
  1550. X    code = prog;
  1551. X    clearregs();
  1552. X    last = findreg();
  1553. X    code = prog;
  1554. X    _SAVE(0); /* value is or'ed in later */
  1555. X    loadimm(ry,DEF_Y-1);
  1556. X    remem1 = code;
  1557. X    loadimm(rx,DEF_X-1);
  1558. X    remem2 = code;
  1559. X    gen(t);
  1560. X    _SB(result,base,offset);
  1561. X    _ADDI(offset,-1,offset);
  1562. X    _CMP(rx,zero);
  1563. X    *code = _B(NE,remem2-code); code++;
  1564. X    _ADDI(rx,-1,rx);
  1565. X    _CMP(ry,zero);
  1566. X    *code = _B(NE,remem1-code); code++;
  1567. X    _ADDI(ry,-1,ry);
  1568. X    _RET;
  1569. X    _RESTORE;
  1570. X    *prog |= (-(sppmax+80))&017777;
  1571. X    dodump(prog, (code - prog) * sizeof (Inst));
  1572. X    progp(buf[0].data, (DEF_X*DEF_Y) - 1, mul, div, mod);
  1573. X}
  1574. X
  1575. Xstatic int mul(int a, int b) {
  1576. X    return a*b;
  1577. X}
  1578. X
  1579. Xstatic int div(int a, int b) {
  1580. X    return a/b;
  1581. X}
  1582. X
  1583. Xstatic int mod(int a, int b) {
  1584. X    return a%b;
  1585. X}
  1586. X
  1587. Xstatic void gen(Tree *t) {
  1588. X    Inst *remem;
  1589. X    int i, saved, b1, b2, c1, c2;
  1590. X    switch (t->t) {
  1591. X    case Num:
  1592. X        if (t->i == 0) {
  1593. X            result = zero;
  1594. X            ccset = 0;
  1595. X            boolean = 1;
  1596. X        } else {
  1597. X            loadimm(result = last, t->i);
  1598. X            boolean = !(t->i & ~1);
  1599. X            ccset = 1;
  1600. X        }
  1601. X        break;
  1602. X    case Xcoord:
  1603. X        result = rx;
  1604. X        boolean = 0;
  1605. X        ccset = 0;
  1606. X        break;
  1607. X    case Ycoord:
  1608. X        result = ry;
  1609. X        boolean = 0;
  1610. X        ccset = 0;
  1611. X        break;
  1612. X    case Bang:
  1613. X        gen(t->kids[0]);
  1614. X        if (!ccset)
  1615. X            _CMP(result,zero);
  1616. X        *code++ = _B(EQ,3);
  1617. X        _ADDIcc(zero,1,last);
  1618. X        _ADDIcc(zero,0,last);
  1619. X        result = last;
  1620. X        boolean = 1;
  1621. X        ccset = 1;
  1622. X        break;
  1623. X    case Not:
  1624. X        gen(t->kids[0]);
  1625. X        _XORIcc(result,-1,last);
  1626. X        result = last;
  1627. X        boolean = 0;
  1628. X        ccset = 1;
  1629. X        break;
  1630. X    case Neg:
  1631. X        gen(t->kids[0]);
  1632. X        _SUBcc(zero,result,last);
  1633. X        result = last;
  1634. X        boolean = 0;
  1635. X        ccset = 1;
  1636. X        break;
  1637. X    case Cond:
  1638. X        gen(t->kids[0]);        /* test */
  1639. X        if (!ccset)
  1640. X            _CMP(result,zero);
  1641. X        remem = code;
  1642. X        *code++ = _B(EQ,0);
  1643. X        _NOP;
  1644. X        gen(t->kids[1]);        /* iftrue */
  1645. X        b1 = boolean;
  1646. X        c1 = ccset;
  1647. X        if (result != last)
  1648. X            _ADD(result,zero,last);
  1649. X        *remem |= code - remem + 1;
  1650. X        remem = code - 1;
  1651. X        *code = code[-1];
  1652. X        code[-1] = _B(ALWAYS,0);    /* fill delay slot */
  1653. X        code++;
  1654. X        gen(t->kids[2]);        /* iffalse */
  1655. X        b2 = boolean;
  1656. X        c2 = ccset;
  1657. X        if (result != last)
  1658. X            _ADD(result,zero,last);
  1659. X        result = last;
  1660. X        boolean = (b1 & b2);
  1661. X        ccset = (c1 & c2);
  1662. X        *remem |= code - remem;
  1663. X        break;
  1664. X    case Andalso:
  1665. X    case Orelse:
  1666. X        gen(t->kids[0]);
  1667. X        b1 = boolean;
  1668. X        if (result != last)
  1669. X            _ADDcc(result,zero,last);
  1670. X        else if (!ccset)
  1671. X            _CMP(result,zero);
  1672. X        saved = last;
  1673. X        remem = code;
  1674. X        if (t->t == Andalso)
  1675. X            *code++ = _B(EQ,0);
  1676. X        else
  1677. X            *code++ = _B(NE,0);
  1678. X        _NOP;
  1679. X        gen(t->kids[1]);
  1680. X        b2 = boolean;
  1681. X        if (result != saved) {
  1682. X            _ADDcc(result,zero,saved);
  1683. X            ccset = 1;
  1684. X        }
  1685. X        result = saved;
  1686. X        *remem |= code - remem;
  1687. X        if (!(b1&b2)) {        /* "normalize" expr to {0,1} */
  1688. X            if (!ccset)
  1689. X                _CMP(result,0);
  1690. X            *code++ = _B(NE,3);
  1691. X            _ADDIcc(zero,0,result);
  1692. X            _ADDIcc(zero,1,result);
  1693. X            ccset = 1;
  1694. X        }
  1695. X        boolean = 1;
  1696. X        break;
  1697. X    case Coordpair:
  1698. X        if (t->i > nfiles || t->i < 0)
  1699. X            error("no such buffer");
  1700. X        if (t->kids[0] != NULL) {
  1701. X            gen(t->kids[0]);
  1702. X            i = last;
  1703. X        } else
  1704. X            i = offset;
  1705. X        loadimm(tmp,(int)buf[t->i].data);
  1706. X        _LBU(last,tmp,i);
  1707. X        result = last;
  1708. X        ccset = 0;
  1709. X        boolean = 0;
  1710. X        break;
  1711. X    default:
  1712. X        gen(t->kids[0]);
  1713. X        saved = result;
  1714. X        if (((Tree *)t->kids[1])->t == Num && (i = ((Tree *)t->kids[1])->i) < 4096 && i > -4096) {
  1715. X            binconst(t,result,i,last);
  1716. X        } else {
  1717. X            if (saved != rx && saved != ry && (last = findreg()) == -1) {
  1718. X                last = saved;
  1719. X                saved = -1;
  1720. X                _PUSH(last);
  1721. X            }
  1722. X            gen(t->kids[1]);
  1723. X            if (saved == -1) {
  1724. X                _POP(tmp);
  1725. X                binop(t,tmp,result,last);
  1726. X            } else {
  1727. X                binop(t,saved,result,last);
  1728. X                if (saved != rx && saved != ry)
  1729. X                    freereg(saved);
  1730. X            }
  1731. X        }
  1732. X        result = last;
  1733. X    }
  1734. X}
  1735. X
  1736. Xstatic void binop(Tree *t, int s1, int s2, int d) {
  1737. X    boolean = 0;
  1738. X    ccset = 1;
  1739. X    switch (t->t) {
  1740. X    default:
  1741. X        error("not a binop in binop!");
  1742. X    case Add:
  1743. X        _ADDcc(s1,s2,d);
  1744. X        break;
  1745. X    case Sub:
  1746. X        _SUBcc(s1,s2,d);
  1747. X        break;
  1748. X    case Mult:
  1749. X        _ADD(zero,s1,o0);
  1750. X        _JAL(a_mul);
  1751. X        _ADD(zero,s2,o1);
  1752. X        _ADDcc(zero,o0,d);
  1753. X        break;
  1754. X    case Div:
  1755. X        _ADD(zero,s1,o0);
  1756. X        _JAL(a_div);
  1757. X        _ADD(zero,s2,o1);
  1758. X        _ADDcc(zero,o0,d);
  1759. X        break;
  1760. X    case Mod:
  1761. X        _ADD(zero,s1,o0);
  1762. X        _JAL(a_mod);
  1763. X        _ADD(zero,s2,o1);
  1764. X        _ADDcc(zero,o0,d);
  1765. X        break;
  1766. X    case Gt:
  1767. X        _CMP(s1,s2);
  1768. X        *code++ = _B(GT,3);
  1769. X        _ADDIcc(zero,0,d);
  1770. X        _ADDIcc(zero,1,d);
  1771. X        boolean = 1;
  1772. X        break;
  1773. X    case Lt:
  1774. X        _CMP(s1,s2);
  1775. X        *code++ = _B(LT,3);
  1776. X        _ADDIcc(zero,0,d);
  1777. X        _ADDIcc(zero,1,d);
  1778. X        boolean = 1;
  1779. X        break;
  1780. X    case Ge:
  1781. X        _CMP(s1,s2);
  1782. X        *code++ = _B(GE,3);
  1783. X        _ADDIcc(zero,0,d);
  1784. X        _ADDIcc(zero,1,d);
  1785. X        boolean = 1;
  1786. X        break;
  1787. X    case Le:
  1788. X        _CMP(s1,s2);
  1789. X        *code++ = _B(LE,3);
  1790. X        _ADDIcc(zero,0,d);
  1791. X        _ADDIcc(zero,1,d);
  1792. X        boolean = 1;
  1793. X        break;
  1794. X    case Eq:
  1795. X        _CMP(s1,s2);
  1796. X        *code++ = _B(EQ,3);
  1797. X        _ADDIcc(zero,0,d);
  1798. X        _ADDIcc(zero,1,d);
  1799. X        boolean = 1;
  1800. X        break;
  1801. X    case Ne:
  1802. X        _CMP(s1,s2);
  1803. X        *code++ = _B(NE,3);
  1804. X        _ADDIcc(zero,0,d);
  1805. X        _ADDIcc(zero,1,d);
  1806. X        boolean = 1;
  1807. X        break;
  1808. X    case Xor:
  1809. X        _XORcc(s1,s2,d);
  1810. X        break;
  1811. X    case And:
  1812. X        _ANDcc(s1,s2,d);
  1813. X        break;
  1814. X    case Or:
  1815. X        _ORcc(s1,s2,d);
  1816. X        break;
  1817. X    case Ll:
  1818. X        _SLL(s1,s2,d);
  1819. X        ccset = 0;
  1820. X        break;
  1821. X    case Rr:
  1822. X        _SRL(s1,s2,d);
  1823. X        ccset = 0;
  1824. X        break;
  1825. X    }
  1826. X}
  1827. X
  1828. Xstatic void binconst(Tree *t, int s1, int s2, int d) {
  1829. X    int shift;
  1830. X    boolean = 0;
  1831. X    ccset = 1;
  1832. X    switch (t->t) {
  1833. X    default:
  1834. X        error("not a binop in binconst!");
  1835. X    case Add:
  1836. X        _ADDIcc(s1,s2,d);
  1837. X        break;
  1838. X    case Sub:
  1839. X        _ADDIcc(s1,-s2,d);
  1840. X        break;
  1841. X    case Mult:
  1842. X    case Div:
  1843. X        if (s2 < 0 || s2 & (s2 - 1) != 0) {
  1844. X            loadimm(s2,o1);
  1845. X            _JAL(((t->t == Mult) ? a_mul : a_div));
  1846. X            _ADD(zero,s1,o0);
  1847. X            _ADDcc(zero,o0,d);
  1848. X        } else {
  1849. X            for (shift = 0; s2 != 0; shift++, s2 >>= 1)
  1850. X                ;
  1851. X            if (shift == 0) {
  1852. X                if (t->t == Mult)
  1853. X                    loadimm(d,0);
  1854. X                else
  1855. X                    error("division by zero");
  1856. X                return;
  1857. X            } else if (t->t == Mult) {
  1858. X                _SLLI(s1,--shift,d);
  1859. X            } else {
  1860. X                _SRLI(s1,--shift,d);
  1861. X            }
  1862. X            ccset = 0;
  1863. X        }
  1864. X        break;
  1865. X    case Mod:
  1866. X        loadimm(s2,o1);
  1867. X        _JAL(a_mod);
  1868. X        _ADD(zero,s1,o0);
  1869. X        _ADDcc(zero,o0,d);
  1870. X        break;
  1871. X    case Gt:
  1872. X        _CMPI(s1,s2);
  1873. X        *code++ = _B(GT,3);
  1874. X        _ADDIcc(zero,0,d);
  1875. X        _ADDIcc(zero,1,d);
  1876. X        boolean = 1;
  1877. X        break;
  1878. X    case Lt:
  1879. X        _CMPI(s1,s2);
  1880. X        *code++ = _B(LT,3);
  1881. X        _ADDIcc(zero,0,d);
  1882. X        _ADDIcc(zero,1,d);
  1883. X        boolean = 1;
  1884. X        break;
  1885. X    case Ge:
  1886. X        _CMPI(s1,s2);
  1887. X        *code++ = _B(GE,3);
  1888. X        _ADDIcc(zero,0,d);
  1889. X        _ADDIcc(zero,1,d);
  1890. X        boolean = 1;
  1891. X        break;
  1892. X    case Le:
  1893. X        _CMPI(s1,s2);
  1894. X        *code++ = _B(LE,3);
  1895. X        _ADDIcc(zero,0,d);
  1896. X        _ADDIcc(zero,1,d);
  1897. X        boolean = 1;
  1898. X        break;
  1899. X    case Eq:
  1900. X        _CMPI(s1,s2);
  1901. X        *code++ = _B(EQ,3);
  1902. X        _ADDIcc(zero,0,d);
  1903. X        _ADDIcc(zero,1,d);
  1904. X        boolean = 1;
  1905. X        break;
  1906. X    case Ne:
  1907. X        _CMPI(s1,s2);
  1908. X        *code++ = _B(NE,3);
  1909. X        _ADDIcc(zero,0,d);
  1910. X        _ADDIcc(zero,1,d);
  1911. X        boolean = 1;
  1912. X        break;
  1913. X    case Xor:
  1914. X        _XORIcc(s1,s2,d);
  1915. X        break;
  1916. X    case And:
  1917. X        _ANDIcc(s1,s2,d);
  1918. X        break;
  1919. X    case Or:
  1920. X        _ORIcc(s1,s2,d);
  1921. X        break;
  1922. X    case Ll:
  1923. X        _SLLI(s1,s2,d);
  1924. X        ccset = 0;
  1925. X        break;
  1926. X    case Rr:
  1927. X        _SRLI(s1,s2,d);
  1928. X        ccset = 0;
  1929. X        break;
  1930. X    }
  1931. X}
  1932. X
  1933. Xstatic void dodump(Inst *prog, int size) {
  1934. X    if (debug) {
  1935. X        int fd = creat("pico.out", 0644);
  1936. X        struct exec exec;
  1937. X        exec.a_machtype = M_SPARC;
  1938. X        exec.a_magic    = OMAGIC;
  1939. X        exec.a_text    = size;
  1940. X        exec.a_data    = 0;
  1941. X        exec.a_bss    = 0;
  1942. X        exec.a_syms    = 0;
  1943. X        exec.a_entry    = 0;
  1944. X        exec.a_trsize    = 0;
  1945. X        exec.a_drsize    = 0;
  1946. X        if (fd < 0) {
  1947. X            perror("pico.out");
  1948. X            exit(1);
  1949. X        }
  1950. X        write(fd, &exec, sizeof exec);
  1951. X        write(fd, prog, size);
  1952. X        close(fd);
  1953. X    }
  1954. X}
  1955. X
  1956. Xstatic void clearregs() {
  1957. X    int i;
  1958. X    for (i = 0; i < 6; i++)
  1959. X        regs[i] = 0;
  1960. X}
  1961. X
  1962. Xstatic void freereg(int i) {
  1963. X    regs[i-18] = 0;
  1964. X}
  1965. X
  1966. Xstatic int findreg() {
  1967. X    int i;
  1968. X    for (i = 0; i < 6; i++)
  1969. X        if (regs[i] == 0)
  1970. X            break;
  1971. X    if (i == 6)
  1972. X        return -1;
  1973. X    regs[i] = 1;
  1974. X    return i+18;
  1975. X}
  1976. END_OF_FILE
  1977.   if test 10714 -ne `wc -c <'sparcgen.c'`; then
  1978.     echo shar: \"'sparcgen.c'\" unpacked with wrong size!
  1979.   fi
  1980.   # end of 'sparcgen.c'
  1981. fi
  1982. echo shar: End of archive 1 \(of 1\).
  1983. cp /dev/null ark1isdone
  1984. MISSING=""
  1985. for I in 1 ; do
  1986.     if test ! -f ark${I}isdone ; then
  1987.     MISSING="${MISSING} ${I}"
  1988.     fi
  1989. done
  1990. if test "${MISSING}" = "" ; then
  1991.     echo You have the archive.
  1992.     rm -f ark[1-9]isdone
  1993. else
  1994.     echo You still must unpack the following archives:
  1995.     echo "        " ${MISSING}
  1996. fi
  1997. exit 0
  1998. exit 0 # Just in case...
  1999. -- 
  2000. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2001. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2002. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2003. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2004.